home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
gnu
/
gnulib
/
libsrc98.zoo
/
pipe.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-01
|
6KB
|
167 lines
#include <fcntl.h>
#include <stat.h>
#include <types.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "lib.h"
#define __MINT__
#include <mintbind.h>
extern int __mint;
#if defined(DEBUG)
# include <stdio.h>
#endif
#ifndef _COMPILER_H
# include <compiler.h>
#endif
__EXTERN char *tmpnam __PROTO((char *buf));
/**
** (sjk)++ These routines simulate a eunchs pipe() call using temporary
** files. A linked list of type *_pipe is kept as to allow as
** many open pipes as there are valid file descriptors. The only
** problem is that the pipe is initiallialy opened for writing,
** and all output must be done to the pipe, then call pipeclose(fd);
** and it sets up the pipe for reading. After all input is done,
** call pipeclose(fd) again and this will close the pipe and delete
** the temporary file that the pipe created.
**
**/
struct _pipe { char p_name[40];
char flag; /* "r"-->read, "w"-->write */
int file_des;
struct _pipe *next;
};
static struct _pipe *__pipes = NULL;
static int del_list (struct _pipe *);
__EXTERN int pipeclose __PROTO((int fd));
extern int (*pipeclose_p) __PROTO((int fd));
/*---------------------------------------------------------------------------*/
/* Make a pipe, open the tempory file, set it up for writing, add the pipe */
/* descriptor to our linked list of pipes, and return. */
/*---------------------------------------------------------------------------*/
int pipe(fildes)
int fildes[2];
{ int fd;
char name[40];
struct _pipe *p;
tmpnam(name); /* Make a temporary file name. */
/*----------------------------------------------*/
/* Open the pipe for reading and writing. */
/*----------------------------------------------*/
fd = open(name,O_CREAT | O_TRUNC | O_RDWR | O_PIPE, 0644);
#if defined(DEBUG)
fprintf(stderr,"opened pipe - fd : %d.\n",fd);
#endif
if (fd < 0)
#if defined(DEBUG)
fprintf(stderr,"fd returns : %d! PIPE(%s) failed.\n",fd, name);
#else
/* nothing */;
#endif
else
{ /*------------------------------------------*/
/* Get a pipe description block and */
/* put in the (1)file name, */
/* (2)file descriptor, */
/* (3)file mode = "w". */
/*------------------------------------------*/
/*-------------------------------------------------------------------*/
p = (struct _pipe *)malloc(sizeof (struct _pipe));
strcpy(p->p_name,name); /* fill in name. */
p->flag = 'w'; /* initially for write. */
p->file_des = fd; /* fill in the pipe descriptor. */
if(!__pipes)
pipeclose_p = pipeclose; /* patch in addr of close routine */
/*-------------------------------------------------------------------*/
p->next = __pipes; /* Link to our list of open pipes. */
__pipes = p;
/*-------------------------------------------------------------------*/
fildes[0] = fildes[1] = fd; /* we fill in fildes[]. */
if (__mint)
(void) Fcntl(fd,0L,2); /* Make fd shared across Pexecs() */
}
return(fd); /* Return the file descriptor. */
}
/*---------------------------------------------------------------------*/
/* close a pipe, if the pipe was open for writing, set it to a read */
/* read pipe, and lseek to the begining of the pipe. if it was open */
/* for reading then close the pipe, delete the temporary file, and */
/* remove the pipe descriptor from the __pipes linked list. */
/*---------------------------------------------------------------------*/
int
pipeclose(fd)
int fd;
{ struct _pipe *p;
int ifd;
for (p=__pipes; p; p=p->next)
{ if (fd == p->file_des)
{
#if defined(DEBUG)
fprintf(stderr,"Deleting pipe - mode : %c, fd : %d\n",p->flag,fd);
#endif
if (p->flag == 'r')
{ int res;
ifd = __OPEN_INDEX(fd);
__open_stat[ifd].pipe = 0; /* So close wont recurse */
res = close(fd);
unlink(p->p_name); /* Delete it. */
del_list(p); /* delete from the list. */
return(res);
}
else
if (p->flag =='w')
{ p->flag = 'r'; /* now make it read. */
lseek(p->file_des,0,SEEK_SET); /* read from the start. */
return(0);
}
}
}
#if defined(DEBUG)
fprintf(stderr,"attempt to close nonexistant pipe.\n");
#endif
return(-1);
}
/*---------------------------------------------------------------------*/
/* delete a pipe descriptor from our list of pipes rooted ar __pipes. */
/*---------------------------------------------------------------------*/
static int del_list(p)
struct _pipe *p;
{ struct _pipe *q,*r;
if (p == __pipes) /* Is it the first element? */
{ __pipes = p->next;
free(p);
return(0);
}
else
{ r = __pipes->next; q = __pipes; /* No it is interior. */
for (; r; r = r->next)
{ if (r == p)
{ q->next = r->next; /* pass over it. */
free(r); /* free its space. */
return(0); /* go home. */
}
q = r; /* update trailing pointer. */
}
}
#if defined(DEBUG)
fprintf(stderr,"Attempt to delete a nonexisting pipe form list (__pipes).");
#endif
return(-1);
}